package com.enjoyireland.hiking;

import java.io.IOException;
import java.io.InputStream;

import org.osmdroid.tileprovider.MapTileProviderBasic;
import org.osmdroid.tileprovider.tilesource.ITileSource;
import org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapController;
import org.osmdroid.views.MapView;
import org.osmdroid.views.overlay.MyLocationOverlay;
import org.osmdroid.views.overlay.ScaleBarOverlay;
import org.osmdroid.views.overlay.TilesOverlay;

import uk.me.jstott.jcoord.IrishRef;
import uk.me.jstott.jcoord.LatLng;
import android.content.Intent;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.location.Location;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Toast;

/**
 * Display topological map (opencyclemap) for specified Walk ID
 *  - mapview is from osmdroid
 *  - Obtain grid reference for walk from DB
 *  - Load map centered on grid reference, or if available, start of gpx track
 * 	- If exists for walk, load GPX track overlay
 * 
 * @author rmacantsaoir
 *
 */
public class WalkView extends Fragment implements Constants, LoaderCallbacks<Void> {

    /** Use several tile providers in sequence */
    private MapTileProviderBasic _mapArray;
    
    GPXViewer gpx;
    
    private Location _startingPoint;
    
    private SQLiteDatabase 		_walkDB;
    private WalkDBHelper 		_walkDBHelper;
    private View				_root;
    private LatLng				_walkLocation;
    private MapView         	_map;
    private MapController   	_mapController;
    private MyLocationOverlay	_myLocation;

    @Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
	        Bundle savedInstanceState) {
		return _root = inflater.inflate(R.layout.walk, container, false);
	}
    
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
		setRetainInstance(true);
		setHasOptionsMenu(true);
		
		// get map data for walk with specified _id
		Uri _id = getActivity().getIntent().getData();
		_walkDBHelper = new WalkDBHelper(getActivity());
		_walkDB = _walkDBHelper.getReadableDatabase();
		String[] data = _walkDBHelper.getGPSData(_walkDB,_id);
		_walkDB.close();
		
        _map = (MapView) _root.findViewById(R.id.mapview);
        _map.setTileSource(CYCLEMAP);
        _map.setBuiltInZoomControls(true);
        _mapController = _map.getController();
        _mapController.setZoom(13);
        
        /* If db contains gpx file name for intended walk, load gpx from resources */
        InputStream gpxStream = null;
        try {
        	if (!data[1].equals("none"))
        		gpxStream = getActivity().getAssets().open("data/" + data[1]);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        
        /* parse GPX file into PathOverlay */
		if (gpxStream!=null){
			gpx = new GPXViewer(gpxStream,_map);
		}

        /* if no gpx file exists for walk, center map on grid reference */
		if (_startingPoint == null){
	        IrishRef i = new IrishRef(data[0]);
	        _walkLocation = i.toLatLng();
	        _startingPoint = new Location("startingPoint: "+data[0]);
	        _startingPoint.setLatitude(_walkLocation.getLatitude());
	        _startingPoint.setLongitude(_walkLocation.getLongitude());
		}
        /* load layout from xml */
        MapUtils res = new MapUtils(getActivity().getApplicationContext());
        
        /* add zoom buttons */
        _map.setBuiltInZoomControls(true);
        
        /* reset map tile providers */
        _mapArray = new MapTileProviderBasic(getActivity().getApplicationContext(),CYCLEMAP);
        _map.getOverlayManager().clear();
        final TilesOverlay tilesOverlay = new TilesOverlay(
        	    _mapArray, getActivity().getBaseContext());
        tilesOverlay.setLoadingBackgroundColor(Color.TRANSPARENT);
        _map.getOverlays().add(tilesOverlay);
        
        /* add compass and location overlay */
        _myLocation = new MyLocationOverlay(getActivity().getBaseContext(), _map, res);
        _myLocation.enableMyLocation();
        
        /* add scale bar overlay */
        ScaleBarOverlay scale = new ScaleBarOverlay(getActivity(),res);
        _map.getOverlays().add(scale);
        // place in middle of upper screen, with 1/2 inch padding
        scale.setScaleBarOffset(getResources().getDisplayMetrics().widthPixels
				/ 2 - getResources().getDisplayMetrics().xdpi / 2, 10);
       
		/* Set map to first position in gpx */
		_mapController = _map.getController();
		/* turn on pinch zoom */
		_map.setMultiTouchControls(true);
		// appropriate zoom level for initial view of map
		_mapController.setZoom(13);
		_mapController.setCenter(new GeoPoint(_startingPoint));
    }
    
    /* save status on pause*/
	@Override
	public void onPause() {
		_myLocation.disableMyLocation();
		_myLocation.disableCompass();
		super.onPause();
	}
	
    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    	// bugfix for when there's no gpx track
    	if (gpx == null)
    		Toast.makeText(getActivity(), "No GPX file for this walk...",Toast.LENGTH_LONG).show();
    	else{
			_startingPoint = gpx._startingPoint;
			if (_startingPoint!=null){
				_mapController.setCenter(new GeoPoint(_startingPoint));
				menu.add(0,0,0,R.string.nav).setIcon(R.drawable.direction_arrow);
			}
    	}
	} 
    
    // add option to navigate to starting point / grid reference of walk
	public boolean onNavigateSelected(MenuItem item){
		try{startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:ll=" + _startingPoint.getLatitude() + "," + _startingPoint.getLongitude())));}
		// tell user if google navigator is not found
		catch(Exception e){
			Toast.makeText(getActivity(), "Google Navigator not installed...",
			          Toast.LENGTH_SHORT).show();
		}
		return true;
	}
	
	public void startNavigating(View v){
		// bugfix for when there's no gpx track
		if (gpx == null){
			Toast.makeText(getActivity(), "No GPX file for this walk...",
			          Toast.LENGTH_LONG).show();
		}
		else{
			_startingPoint = gpx._startingPoint;
			if (_startingPoint!=null){
				_mapController.setCenter(new GeoPoint(_startingPoint));
				try{startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("google.navigation:ll=" + _startingPoint.getLatitude() + "," + _startingPoint.getLongitude())));}
				// tell user if google navigator is not found
				catch(Exception e){
					Toast.makeText(getActivity(), "Google Navigator not installed...",
					          Toast.LENGTH_LONG).show();
				}
			}
			else{
				Toast.makeText(getActivity(), "Still parsing GPX file...",
				          Toast.LENGTH_LONG).show();
			}
		}
	}
	
    /* if returning from pause, restore status */
	@Override
	public void onResume() {
		super.onResume();
		final String tileSourceName = "CYCLEMAP";
		try {
			final ITileSource tileSource = TileSourceFactory.getTileSource(tileSourceName);
			_map.setTileSource(tileSource);
		} catch (final IllegalArgumentException ignoreThis) {
		}
		_myLocation.enableMyLocation();
		_myLocation.enableCompass();
	}

	@Override
	public Loader<Void> onCreateLoader(int arg0, Bundle arg1) {
		// TODO Auto-generated method stub
		return null;
	}
	
	@Override
	public void onLoadFinished(Loader<Void> arg0, Void arg1) {
		// TODO Auto-generated method stub
		
	}
	
	@Override
	public void onLoaderReset(Loader<Void> arg0) {
		// TODO Auto-generated method stub
		
	}
}
